package com.aia.prm.web.ria.app;

import java.net.SocketException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.aia.prm.web.ria.app.ui.G2View;
import com.aia.prm.web.ria.app.ui.LoginView;
import com.cfh.domain.User;
import com.vaadin.terminal.ErrorMessage;
import com.vaadin.terminal.ParameterHandler;
import com.vaadin.terminal.SystemError;
import com.vaadin.terminal.Terminal.ErrorListener;
import com.vaadin.terminal.URIHandler;
import com.vaadin.terminal.VariableOwner;
import com.vaadin.terminal.gwt.server.ChangeVariablesErrorEvent;
import com.vaadin.terminal.gwt.server.HttpServletRequestListener;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.UriFragmentUtility;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;

@SuppressWarnings("serial")
public class PrmApplication extends AbstractApplication implements HttpServletRequestListener {
	private static final Logger logger = Logger.getLogger(PrmApplication.class);
	private static ThreadLocal<PrmApplication> currentApplication = new ThreadLocal<PrmApplication>();
	final UriFragmentUtility urifu = null;
	private Window window = null;
	private MyURIHandlerForQne myURIHandlerForQne;

	private String contextPath = "/aio2";
	private static String contextPathRoot = "/blue";

	private boolean contextPathHasSet = false;

	@Override
	public void init() {
		setTheme("g2");
		System.out.println(" > Version 1.2");
		window = new Window("g2_console");
		window.setSizeFull();
		window.setContent(new LoginView(this));

		setMainWindow(window);

		// https://vaadin.com/book/-/page/advanced.resources.html
		setMyURIHandlerForQne(new MyURIHandlerForQne(this));
		window.addURIHandler(getMyURIHandlerForQne());

		UriFragmentUtility urifu = new UriFragmentUtility();
		getMainWindow().addComponent(urifu);

		urifu.addListener(new MyFragmentChangedListener(this));

		setErrorHandler(new ErrorListener() {
			public void terminalError(com.vaadin.terminal.Terminal.ErrorEvent event) {
				final Throwable t = event.getThrowable();
				if (t instanceof SocketException) {
					// Most likely client browser closed socket
					logger.info("SocketException in CommunicationManager." + " Most likely client (browser) closed socket.");
					return;
				}

				// Finds the original source of the error/exception
				Object owner = null;
				if (event instanceof VariableOwner.ErrorEvent) {
					owner = ((VariableOwner.ErrorEvent) event).getVariableOwner();
				} else if (event instanceof URIHandler.ErrorEvent) {
					owner = ((URIHandler.ErrorEvent) event).getURIHandler();
				} else if (event instanceof ParameterHandler.ErrorEvent) {
					owner = ((ParameterHandler.ErrorEvent) event).getParameterHandler();
				} else if (event instanceof ChangeVariablesErrorEvent) {
					owner = ((ChangeVariablesErrorEvent) event).getComponent();
				}

				// Shows the error in AbstractComponent
				if (owner instanceof AbstractComponent) {
					if (t instanceof ErrorMessage) {
						((AbstractComponent) owner).setComponentError((ErrorMessage) t);
					} else {
						((AbstractComponent) owner).setComponentError(new SystemError(t));
					}
				}

				// also print the error on console
				logger.error("Terminal error:", t);
				getMainWindow().showNotification("Terminal error:" + t, Notification.TYPE_WARNING_MESSAGE);
			}
		});
	}

	void falstLogin() {
		User usr = new User();
		usr.setPASSWORD("asdfpqwfnasokdfjqopnfa;fnqwuinfgasdkfa;dfjqopwgniq;sdfjasl;dfnqfn");
		usr.setUSER_NAME("debug user");
		usr.setLOGIN_NAME("debug");

		setUser(usr);
		getMainWindow().removeAllComponents();
		G2View g2View = new G2View(this);
		getMainWindow().setContent(g2View);
	}

	@Override
	public void close() {
		super.close();
		logger.debug(" App close");
	}

	public void onRequestStart(HttpServletRequest request, HttpServletResponse response) {
		setInstance(this);
	}

	public void onRequestEnd(HttpServletRequest request, HttpServletResponse response) {
		try {
			HttpSession session = request.getSession();
			// logger.debug("onRequestStart - session 01");
			if (this.getUser() != null && session.getAttribute("PrmApplication_user") == null) {
				// logger.debug("onRequestStart - session 02");
				session.setAttribute("PrmApplication_user", this.getUser());
			}
		} catch (Exception e) {
			logger.error("cannot set session onRequestStart", e);
		}

		try {
			if (!contextPathHasSet) {
				String cp = request.getContextPath();
				setContextPath(cp);
				logger.debug("set contextPath to:" + cp);
			}
		} catch (Exception e) {
			logger.error("cannot set contextPath", e);
		}

		setInstance(null);
	}

	private static void setInstance(PrmApplication application) {
		currentApplication.set(application);
	}

	public static PrmApplication getInstance() {
		return currentApplication.get();
	}



	public MyURIHandlerForQne getMyURIHandlerForQne() {
		return myURIHandlerForQne;
	}

	public void setMyURIHandlerForQne(MyURIHandlerForQne myURIHandlerForQne) {
		this.myURIHandlerForQne = myURIHandlerForQne;
	}

	public String getContextPath() {
		return contextPath;
	}

	public String getFullContextPath() {
		return contextPath + contextPathRoot;
	}

	public void setContextPath(String contextPath) {
		this.contextPath = contextPath;
	}

}
